package logic

import (
	"common/globals"
	"common/model"
	"common/pkg"
	"context"
	"errors"
	"github.com/google/uuid"
	order "order_srv/proto"
	"strconv"
	"time"
)

func (o *OrderServer) OrderAdd(ctx context.Context, req *order.OrderAddRequest) (*order.OrderAddResponse, error) {
	lockKey := "lock:" + strconv.Itoa(int(req.Userid))
	if !globals.Rdb.SetNX(context.Background(), lockKey, "111", 8*time.Minute).Val() {
		return nil, errors.New("请勿重复下单")
	}
	defer globals.Rdb.Del(context.Background(), lockKey)
	mealKey := "mealProductList:" + strconv.Itoa(int(req.MealProductId))
	res, _ := globals.Rdb.LLen(ctx, mealKey).Result()
	if res < req.Num {
		return nil, errors.New("库存不足")
	}
	//此处挨个去取 需要完善   需要考虑某一次取失败的话 前面取出来的需要回滚
	for i := 0; i < int(req.Num); i++ {
		err := globals.Rdb.RPop(context.Background(), mealKey).Err()
		if err != nil {
			return nil, err
		}
	}
	var meal model.MealProduct
	err := meal.GetMealProductInfoById(int(req.MealProductId))
	if err != nil {
		return nil, err
	}
	if meal.ID == 0 {
		return nil, errors.New("库存不足")
	}
	totalPrice := meal.MealProductPrice * float64(req.Num)
	OrderId := uuid.New().String()
	if req.CouponId != 0 {
		var coupon model.UserCoupon
		err = coupon.GetCouponById(int(req.CouponId))
		if err != nil {
			return nil, err
		}
		if coupon.ID == 0 || coupon.UserId != int(req.Userid) || coupon.HowMoneyAvailable > totalPrice || coupon.Status != "未过期" {
			return nil, errors.New("当前优惠券无法使用 请重新选择 ")
		}
		tx := globals.Db.Begin()
		ActualPrice := totalPrice - coupon.CouponPrice
		orderCreate := model.Order{
			OrderId:       OrderId,
			UserId:        int(req.Userid),
			MealProductId: int(req.MealProductId),
			Num:           int(req.Num),
			PayType:       int(req.PayType),
			TotalPrice:    totalPrice,
			DiscountPrice: coupon.CouponPrice,
			ActualPrice:   ActualPrice,
		}
		err = orderCreate.Create()
		if err != nil {
			tx.Rollback()
			return nil, err
		}
		err = coupon.UpdateStatusById(int(coupon.ID), "已使用")
		if err != nil {
			tx.Rollback()
			return nil, err
		}
		tx.Commit()
		AliActualPrice := strconv.FormatFloat(ActualPrice, 'f', 2, 64)
		pay, err := pkg.NewAliPay().ALiPay(meal.MealProductName, OrderId, AliActualPrice)
		if err != nil {
			return nil, err
		}
		return &order.OrderAddResponse{PayUrl: pay}, nil
	}
	orderCreate := model.Order{
		OrderId:       OrderId,
		UserId:        int(req.Userid),
		MealProductId: int(req.MealProductId),
		Num:           int(req.Num),
		PayType:       int(req.PayType),
		TotalPrice:    totalPrice,
		DiscountPrice: 0,
		ActualPrice:   totalPrice,
	}
	err = orderCreate.Create()
	if err != nil {
		return nil, err
	}
	AliActualPrice := strconv.FormatFloat(totalPrice, 'f', 2, 64)
	pay, err := pkg.NewAliPay().ALiPay(meal.MealProductName, OrderId, AliActualPrice)
	if err != nil {
		return nil, err
	}
	return &order.OrderAddResponse{PayUrl: pay}, nil
}
